#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from direct.directbase import DirectStart
from direct.showbase.DirectObject import DirectObject

from pandac.PandaModules import *
from direct.interval.IntervalGlobal import *
from direct.actor.Actor import Actor

from panda3d.core import *
from panda3d.physics import *

from key import Key

import random,math,sys
show_col=False
FPS = 40

class Game(DirectObject):
	def initGirl(self):
		self.girl = Actor()
		self.girl.loadModel('data/models/female.bam')
		self.girl.loadAnims({'machanie':'data/models/female-anim1.bam'})

		self.girl.setTwoSided(True)
		self.girl.node().setBounds(OmniBoundingVolume())
		self.girl.node().setFinal(True)
		self.girl.reparentTo(render)
		self.girl.setZ(-26.0)
		self.girl.setY(65.0)
		self.girl.setScale(2.0)
		self.girl.actorInterval("machanie").loop()
		
		#myNodePath = self.girl.controlJoint(None,"modelRoot","UpperArm_L")
		#myNodePath.setPos(10,0,0)

	def initHand(self):
		self.normal_hand=loader.loadModel('data/models/hand.bam')
		self.normal_hand.reparentTo(render)
		
		self.hand=self.normal_hand
		
		#self.drill.setHpr(0,90,0)
		self.hand.setHpr(-20+180,90,0)
		self.hand.setPos(0.0,0.0,1.5)
		self.hand.setScale(2.0)

		self.drillGroundCol = CollisionNode('drillSphere')
		self.drillGroundCol.addSolid(CollisionSphere(0.0, 0.0, 0.0, 0.9))
		self.drillGroundCol.setFromCollideMask(BitMask32.bit(1))
		self.drillGroundCol.setIntoCollideMask(BitMask32.allOff())

		self.drillGroundColNp = self.hand.attachNewNode(self.drillGroundCol)
		self.drillGroundHandler = CollisionHandlerQueue()
		self.cTrav.addCollider(self.drillGroundColNp, self.drillGroundHandler)

		# Uncomment this line to see the collision rays
		if show_col: self.drillGroundColNp.show()

		# Uncomment this line to show a visual representation of the 
		# collisions occuring
		if show_col: self.cTrav.showCollisions(render)

	def initCollisionDetection(self):
		'''
		base.cTrav = CollisionTraverser()
		base.cTrav.showCollisions(render)
		self.notifier = CollisionHandlerEvent()
		self.notifier.addInPattern("%fn-in-%in")
		self.accept("drill-in-wolf", self.onCollision)

		self.wallCollisionData=[False]
		'''
		self.cTrav = CollisionTraverser()


	def onCollision(self, entry):
		self.key_up=self.key_down=self.key_left=self.key_right=False
		print 1
		
	def initWolfMap(self):
		#self.forestsky=loader.loadModel('data/models/forestsky.egg')
		'''
		self.forestsky=loader.loadModel('data/models/alice-skies--verycloudy/verycloudy.bam')
		self.forestsky.reparentTo(render)
		self.forestsky.setScale(3.0)
		self.forestsky.setZ(-600.0)
		'''

		self.wolfMap=loader.loadModel('data/models/wolf.bam')
		self.wolfMap.reparentTo(render)
		self.wolfMap.setScale(1.0)
		self.wolfMap.setZ(-26.0)
		self.wolfMap.setY(0.0)
		
		#self.wolfMap.find('**/Col1').setZ(100)
		#self.wolfMap.find('**/Col2').setZ(100)
		#self.wolfMap.find('**/Col3').setZ(100)
		
		self.mapGroundCol = CollisionNode('cityCollider')
		
		walls={"left":((-10,-10,0),(-10,10,0),(-10,10,20),(-10,-10,20)),
		       "right":((10,-10,0),(10,10,0),(10,10,20),(10,-10,20)),
		       "top": ((-10,10,0),(10,10,0),(10,10,20),(-10,10,20)),
		       "bottom": ((-10,-10,0),(10,-10,0),(10,-10,20),(-10,-10,20))}
		
		types={"Vertical":("left","right"),
		       "Horizontal":("top","bottom"),
		       "HorizontalDEL":("top","bottom","left"),
		       "HorizontalDER":("top","bottom","right"),
		       "VerticalDET":("top","left","right"),
		       "VerticalDEB":("bottom","left","right"),
		       "CrossDEB":("bottom",),
		       "CrossDET":("top",),
		       "CrossDEL":("left",),
		       "CrossDER":("right",),
		       "CrossDERB":("bottom","right"),
		       "CrossDERT":("top","right"),
		       "CrossDELT":("top","left"),
		       "CrossDELB":("bottom","left")}
		
		for typ,sciany in types.iteritems():
			matches = self.wolfMap.findAllMatches('**/'+typ+'.*')
			for b in matches:
				for wall in sciany:
					sciana=walls[wall]
					quad = CollisionPolygon(Point3(sciana[0][0]+b.getX(), sciana[0][1]+b.getY(), sciana[0][2]),
						                    Point3(sciana[1][0]+b.getX(), sciana[1][1]+b.getY(), sciana[1][2]),
						                    Point3(sciana[2][0]+b.getX(), sciana[2][1]+b.getY(), sciana[2][2]),
						                    Point3(sciana[3][0]+b.getX(), sciana[3][1]+b.getY(), sciana[3][2]))
					self.mapGroundCol.addSolid(quad)
			
		#quad = CollisionPolygon(Point3(0, -10, 0), Point3(0, -10, 20),Point3(0, 19, 20), Point3(0, 19, 0))
		#self.mapGroundCol.addSolid(quad)
		
		self.mapGroundCol.setFromCollideMask(BitMask32.allOff())
		self.mapGroundCol.setIntoCollideMask(BitMask32.bit(1))

		self.mapGroundColNp = self.wolfMap.attachNewNode(self.mapGroundCol)
		self.mapGroundHandler = CollisionHandlerQueue()
		self.cTrav.addCollider(self.mapGroundColNp, self.mapGroundHandler)

		self.wolfMap.flattenStrong()
		
		# Uncomment this line to see the collision rays
		if show_col: self.mapGroundColNp.show()


		#self.wolfMap.setCollideMask(BitMask32.bit(1)) - wąskie gardło, dużo procka żre

	def onDrillCollision(self, entry):
		vel = random.uniform(0.01, 0.2)
		self.girl.setPythonTag("velocity", vel)
		self.girl.wrtReparentTo(self.hand)
		taskMgr.remove("UpdateGirl")

	def keysTask(self,task):
		startpos = self.hand.getPos()
		
		for key in self.keys:
			if key[0].isPressed():
				key[1]()
		
		newpos=self.hand.getPos()
		self.hand.setPos(startpos)
		
		self.hand.setX(newpos[0])
		self.cTrav.traverse(render)
		if self.drillGroundHandler.getNumEntries():
			self.hand.setX(startpos[0])
			
		self.hand.setY(newpos[1])
		self.cTrav.traverse(render)
		if self.drillGroundHandler.getNumEntries():
			self.hand.setY(startpos[1])
			
		'''	
		for i in range(self.drillGroundHandler.getNumEntries()):
			entry = self.drillGroundHandler.getEntry(i)
			#entries.append(entry)
			self.drill.setPos(startpos)
			break
		'''
		return task.cont

	def moveForward(self):
		r = self.hand.getHpr()[2]
		self.hand.setX(self.hand.getX()-math.sin(math.radians(r)))
		self.hand.setY(self.hand.getY()+math.cos(math.radians(r)))

	def moveBackward(self):
		r = self.hand.getHpr()[2]
		self.hand.setX(self.hand.getX()+math.sin(math.radians(r)))
		self.hand.setY(self.hand.getY()-math.cos(math.radians(r)))

	def rotateLeft(self):
		r=self.hand.getHpr()
		self.hand.setHpr(r[0],r[1],r[2]+2.0)

	def rotateRight(self):
		r=self.hand.getHpr()
		self.hand.setHpr(r[0],r[1],r[2]-2.0)

	def __init__(self):
		base.enableParticles() # do fizyki/kolizji
		base.setFrameRateMeter(True) # FPS
		globalClock = ClockObject.getGlobalClock()
		globalClock.setMode(ClockObject.MLimited)
		globalClock.setFrameRate(FPS)
		
		pLight = PointLight( 'pointLight' )
		pLight.setPoint(Point3(0,6,5))
		pLight.setColor(Point4( 0.6, 0.6, 0.6, 1 ))
		pLightNode = render.attachNewNode(pLight)
		render.setLight(pLightNode)

		alight = AmbientLight('alight')
		alight.setColor(VBase4(0.8, 0.8, 0.8, 1))
		alnp = render.attachNewNode(alight)
		render.setLight(alnp)

		self.initCollisionDetection()
		self.initGirl()
		#self.initNoddy()
		self.initHand()
		self.initWolfMap()


		base.setBackgroundColor(0.1,0.2,0.6)
		base.disableMouse()
		'''
		base.camera.setPos(4,-20,7)
		base.camera.lookAt( 0,0,3 )
		'''
		base.camera.setPos(0.0,-6.0,4.0)
		dpos=self.hand.getPos()
		base.camera.lookAt( dpos[0]-0.0,dpos[1],dpos[2]+1.8 )

		base.camera.wrtReparentTo(self.hand)

		#taskMgr.doMethodLater(0.2, self.simulationTask, "Physics Simulation")
		
		self.keys=[(Key("arrow_up"),self.moveForward),(Key("arrow_down"),self.moveBackward),
		           (Key("arrow_left"),self.rotateLeft),(Key("arrow_right"),self.rotateRight)]
		
		Key("escape",sys.exit)
		taskMgr.doMethodLater(0.2, self.keysTask, "Keys Handler")

		self.hand.setPos(0.0,0.0,-16.0)
Game()
run()
